package com.duanzz.mapper;

import com.duanzz.entity.Emp;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.jdbc.SQL;
import org.apache.ibatis.mapping.FetchType;
import org.apache.ibatis.type.JdbcType;

import java.util.Date;
import java.util.List;

/**
 * @author duanzz
 * @description
 * @date 2020/11/17
 */
@CacheNamespace
public interface IEmpMapper {

    /**
     * 根据主键查询
     *
     * @param empno
     * @return
     */
    @Select("select * from emp where empno = #{empno}")
    Emp findEmpById(Integer empno);


    @Results(id = "", value = {
            @Result(id = true, javaType = Integer.class, jdbcType = JdbcType.INTEGER, property =
                    "empno", column = "empno"),
            @Result(javaType = String.class, jdbcType = JdbcType.VARCHAR, property =
                    "ename", column = "ename"),
            @Result(javaType = String.class, jdbcType = JdbcType.VARCHAR, property =
                    "job", column = "job"),
            @Result(javaType = Integer.class, jdbcType = JdbcType.INTEGER, property =
                    "mgr", column = "mgr"),
            @Result(javaType = Date.class, jdbcType = JdbcType.DATE, property =
                    "hiredate", column = "hiredate"),
            @Result(javaType = Double.class, jdbcType = JdbcType.DOUBLE, property =
                    "sal", column = "sal"),
            @Result(javaType = Double.class, jdbcType = JdbcType.DOUBLE, property =
                    "comm", column = "comm"),
            @Result(javaType = Integer.class, jdbcType = JdbcType.INTEGER, property =
                    "deptno", column = "deptno"),
            @Result(property = "dept",  column = "deptno", one = @One(select =
                    "com.duanzz.mapper.IDeptMapper.findDeptById",fetchType = FetchType.EAGER)),
            @Result(property = "roleList", column = "empno", many =
            @Many(select = "com.duanzz.mapper.IRoleMapper.findRoleByEmpno",fetchType = FetchType.LAZY))
    })
    @SelectProvider(type = EmpSqlProvider.class, method = "findEmpByCondition")
    List<Emp> findEmpByCondition(Emp emp);

    @Select("select count(1) from emp")
    int findEmpCount();

    @Select("select * from emp where deptno = #{deptno}")
    List<Emp> findEmpByDeptno(Integer deptno);


    @InsertProvider(type = EmpSqlProvider.class,method = "insertEmp")
    int insertEmp(Emp emp);

    @UpdateProvider(type = EmpSqlProvider.class,method = "updateEmpById")
    int updateEmpById(Emp emp);

    @DeleteProvider(type = EmpSqlProvider.class,method = "deleteEmpById")
    int deleteEmpById(Integer empno);

    class EmpSqlProvider {

        public String findEmpByCondition(Emp emp) {
            return new SQL() {{
                SELECT("*");
                FROM("EMP");
                if (emp.getEmpno() != null) {
                    WHERE("empno = #{empno}");
                }
                if (emp.getEname() != null) {
                    WHERE("ename like concat(#{empno},'%')");
                }
                if (emp.getJob() != null) {
                    WHERE("job = #{job}");
                }
                if (emp.getMgr() != null) {
                    WHERE("mgr = #{mgr}");
                }
                if (emp.getHiredate() != null) {
                    WHERE("hiredate = #{hiredate}");
                }
                if (emp.getSal() != null) {
                    WHERE("sal = #{sal}");
                }
                if (emp.getComm() != null) {
                    WHERE("comm = #{comm}");
                }
                if (emp.getDeptno() != null) {
                    WHERE("deptno = #{deptno}");
                }
            }}.toString();
        }


        public String insertEmp(Emp emp){
            return new SQL(){{
                INSERT_INTO("EMP");
                if(emp.getEmpno()!=null){
                    VALUES("empno","#{empno}");
                }
                if(emp.getEname()!=null){
                    VALUES("ename","#{ename}");
                }
                if(emp.getMgr()!=null){
                    VALUES("mgr","#{mgr}");
                }
                if(emp.getJob()!=null){
                    VALUES("job","#{job}");
                }
                if(emp.getHiredate()!=null){
                    VALUES("hiredate","#{hiredate}");
                }
                if(emp.getSal()!=null){
                    VALUES("sal","#{sal}");
                }
                if(emp.getComm()!=null){
                    VALUES("comm","#{comm}");
                }
                if(emp.getDeptno()!=null){
                    VALUES("deptno","#{deptno}");
                }
            }}.toString();
        }

        public String updateEmpById(Emp emp){
            return new SQL(){{
                UPDATE("EMP");
                if(emp.getEname()!=null){
                    SET("ename = #{ename}");
                }
                if(emp.getMgr()!=null){
                    SET("mgr = #{mgr}");
                }
                if(emp.getJob()!=null){
                    SET("job = #{job}");
                }
                if(emp.getHiredate()!=null){
                    SET("hiredate = #{hiredate}");
                }
                if(emp.getSal()!=null){
                    SET("sal = #{sal}");
                }
                if(emp.getComm()!=null){
                    SET("comm = #{comm}");
                }
                if(emp.getDeptno()!=null){
                    SET("deptno = #{deptno}");
                }
                WHERE("empno = #{empno}");
            }}.toString();

        }

        public String deleteEmpById(Integer empno){
            return new SQL(){{
                DELETE_FROM("EMP");
                WHERE("empno = #{empno}");
            }}.toString();
        }

    }

}
